package com.demo.common.ratelimit.condition;

import com.demo.common.ratelimit.annotation.EnableFxwLimiter;
import com.demo.common.ratelimit.exception.RateLimitException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

/**
 * 限流判断
 *
 * @author DayDayUp
 * @datetime 2023-09-01 12:20
 **/
public class LimiterCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        if (beanFactory == null) {
            throw new RateLimitException("BeanFactory is null, solve the problem.");
        }
        String beanName = beanFactory.getBeanNamesForAnnotation(EnableFxwLimiter.class)[0];
        String beanClassName = beanFactory.getBeanDefinition(beanName).getBeanClassName();
        if (!StringUtils.hasText(beanClassName)) {
            throw new RateLimitException("startup class not found.");
        }
        Class<?> aClass;
        try {
            aClass = ClassUtils.forName(beanClassName, this.getClass().getClassLoader());
        } catch (ClassNotFoundException e) {
            throw new RateLimitException("class can't load.",e);
        }
        EnableFxwLimiter annotation = AnnotationUtils.findAnnotation(aClass, EnableFxwLimiter.class);
        return annotation != null && annotation.limited();
    }
}
